﻿using Inovout.Cloud.Client.Storage.Data;
using Inovout.Cloud.Storage.Services;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Xunit;

namespace Inovout.Cloud.Client.Storage.Tests
{
    public class ObjectTest : StorageTest
    {
        [Fact(DisplayName = "InsertAndUploadObjectWithResumable")]
        public void InsertWithResumable()
        {
            IBucketService bucketService = ComponentRegistry.Resolve<IBucketService>();
            Inovout.Cloud.Storage.Models.Bucket bucket =
                new Inovout.Cloud.Storage.Models.Bucket
                    {
                        Name = "bucket" + DateTime.Now.Ticks.ToString(),
                        Project = CloudProject
                    };
            bucketService.Save(bucket);
            string objectName = "object" + DateTime.Now.Ticks.ToString();

            StorageService storageService = new StorageService(new Inovout.Cloud.Client.Services.BaseClientService.Initializer
            {
                ApiKey = CloudApplicationUser.Application.Name
            });

            var insertObject = storageService.Objects.Insert(
                new Data.Object
                {
                    Name = objectName
                }
                , bucket.Name
                , new MemoryStream(Encoding.UTF8.GetBytes("hello " + objectName)),
                "resumable"
                ).Upload();

            System.IO.MemoryStream ms = new MemoryStream();
            storageService.Objects.Get(bucket.Name, objectName).Download(ms);
            Assert.Equal<long>(ms.Length, 30);
        }
        [Fact(DisplayName = "InsertAndUploadObjectWithMultipart")]
        public void InsertWithMultipart()
        {
            IBucketService bucketService = ComponentRegistry.Resolve<IBucketService>();
            Inovout.Cloud.Storage.Models.Bucket bucket =
                new Inovout.Cloud.Storage.Models.Bucket
                {
                    Name = "bucket" + DateTime.Now.Ticks.ToString(),
                    Project = CloudProject
                };
            bucketService.Save(bucket);
            string objectName = "object" + DateTime.Now.Ticks.ToString();

            StorageService storageService = new StorageService(new Inovout.Cloud.Client.Services.BaseClientService.Initializer
            {
                ApiKey = CloudApplicationUser.Application.Name
            });
            ///upload/v1/b/bucket635179504124540354/o?key=app635179504123610301&uploadType=multipart 

            //curl http://www.sumapp.cn/ --proxy 127.0.0.1:8888 -H "Content-Type: multipart/related; boundary=foo_bar_baz\r\n" -d "--foo_bar_baz" -d "@d:\test.txt"
            string boundary = "1";
            //string boundary = "foo_bar_baz";
            MultipartContent content = new MultipartContent("related", boundary);
            string mediaType = String.Format("multipart/related; boundary={0}", boundary);
            content.Headers.ContentType = MediaTypeHeaderValue.Parse(mediaType);
            content.Add(new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(new 
            {
                name = objectName
            }), Encoding.UTF8, "application/json"));
            StreamContent mediaContent = new StreamContent(new System.IO.MemoryStream(Encoding.UTF8.GetBytes("hello " + objectName)));
            mediaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
            content.Add(mediaContent);
            HttpClient hc = new HttpClient();
            var response = hc.PostAsync(string.Format("{0}b/{1}/o?key={2}&uploadType=multipart",
                storageService.BaseUri, bucket.Name, storageService.ApiKey), content).Result;

            Assert.Equal<bool>(true, response.IsSuccessStatusCode);
            System.IO.MemoryStream ms = new MemoryStream();
            storageService.Objects.Get(bucket.Name, objectName).Download(ms);
            Assert.Equal<long>(ms.Length, 30);
  
        }
        [Fact(DisplayName = "ListObject")]
        public void List()
        {
            IBucketService bucketService = ComponentRegistry.Resolve<IBucketService>();
            Inovout.Cloud.Storage.Models.Bucket bucket =
                new Inovout.Cloud.Storage.Models.Bucket
                {
                    Name = "bucket" + DateTime.Now.Ticks.ToString(),
                    Project = CloudProject
                };
            bucketService.Save(bucket);
            string objectName = "object" + DateTime.Now.Ticks.ToString();

            StorageService storageService = new StorageService(new Inovout.Cloud.Client.Services.BaseClientService.Initializer
            {
                ApiKey = CloudApplicationUser.Application.Name
            });

            var insertObject = storageService.Objects.Insert(
                new Data.Object
                {
                    Name = objectName
                }
                , bucket.Name
                , new MemoryStream(Encoding.UTF8.GetBytes("hello " + objectName)),
                "resumable"
                ).Upload();
            var objectList = storageService.Objects.List(bucket.Name).Execute();

        }
        [Fact(DisplayName = "DeleteObject")]
        public void Delete()
        {
            IBucketService bucketService = ComponentRegistry.Resolve<IBucketService>();
            Inovout.Cloud.Storage.Models.Bucket bucket =
                new Inovout.Cloud.Storage.Models.Bucket
                {
                    Name = "bucket" + DateTime.Now.Ticks.ToString(),
                    Project = CloudProject
                };
            bucketService.Save(bucket);
            string objectName = "object" + DateTime.Now.Ticks.ToString();

            StorageService storageService = new StorageService(new Inovout.Cloud.Client.Services.BaseClientService.Initializer
            {
                ApiKey = CloudApplicationUser.Application.Name
            });
            var insertObject = new Data.Object
                {
                    Name = objectName
                };
            storageService.Objects.Insert(
               insertObject
               , bucket.Name
               , new MemoryStream(Encoding.UTF8.GetBytes("hello " + objectName)),
               "resumable"
               ).Upload();

            storageService.Objects.Delete(bucket.Name, insertObject.Name).Execute();
        }
        [Fact(DisplayName = "CopyToObject")]
        public void CopyTo()
        {
            StorageService storageService = new StorageService(new Inovout.Cloud.Client.Services.BaseClientService.Initializer
                    {
                        ApiKey = CloudApplicationUser.Application.Name
                    });

            ///v1/b/bucket635176201765323728/o/object635176201777514425?

            //storageService.Objects.Get("bucket635176201765323728", "object635176201777514425").Download(new MemoryStream());

            IBucketService bucketService = ComponentRegistry.Resolve<IBucketService>();


            Inovout.Cloud.Storage.Models.Bucket bucket =
                new Inovout.Cloud.Storage.Models.Bucket
                {
                    Name = "bucket" + DateTime.Now.Ticks.ToString(),
                    Project = CloudProject
                };
            bucketService.Save(bucket);
            Inovout.Cloud.Storage.Models.Bucket copyBucket =
                new Inovout.Cloud.Storage.Models.Bucket
                {
                    Name = "bucket" + DateTime.Now.Ticks.ToString(),
                    Project = CloudProject
                };
            bucketService.Save(copyBucket);

            string objectName = "object" + DateTime.Now.Ticks.ToString();


            var insertObject = new Data.Object
            {
                Name = objectName
            };
            storageService.Objects.Insert(
               insertObject
               , bucket.Name
               , new MemoryStream(Encoding.UTF8.GetBytes("hello " + objectName)),
               "resumable"
               ).Upload();
            var copyObject = new Data.Object
            {
                Name = "object" + DateTime.Now.Ticks.ToString()
            };
            copyObject = storageService.Objects.Copy(copyObject,
                bucket.Name, insertObject.Name, copyBucket.Name, copyObject.Name).Execute();

            System.IO.MemoryStream ms = new MemoryStream();
            storageService.Objects.Get(copyBucket.Name, copyObject.Name).Download(ms);
            Assert.Equal<long>(ms.Length, 30);
        }
    }
}
